/**
* @file Queue.c
* @brief 
* @author 
* @date 
* @version 
*/
#include "../include/queue.h"

void *thread_routine();

int Queue_Init(SQueue *queue, int threadNum)
{
    pthread_mutex_init (&(queue->queue_lock), NULL);  
    pthread_cond_init (&(queue->queue_ready), NULL);

    queue ->elem =  (Elem*)malloc(QUEUE_MAXSIZE * sizeof(Elem));
    if (NULL == queue ->elem){
        printf("Init queue falied...\n");
        return -1;
    }
    queue ->front = queue ->rear = 0;
    

    queue->threadid = (pthread_t *) malloc (threadNum * sizeof (pthread_t));  
    int i = 0;  
    for (i = 0; i < threadNum; i++)  
    {   
        pthread_create (&(queue->threadid[i]), NULL, thread_routine,NULL);  
    }

    return 0;
}

// 返回Q的元素个数,即队列的长度
int Queue_Length(SQueue *queue)
{
    return(queue->rear - queue->front + QUEUE_MAXSIZE) % QUEUE_MAXSIZE;
}

bool Queue_isFull(SQueue *queue)
{
    if (queue ->front == (queue ->rear + 1) % QUEUE_MAXSIZE)
        return true;
    else
        return false;
}

bool Queue_isEmpty(SQueue *queue)
{
    if (queue ->front == queue ->rear)
        return true;
    else
        return false;
}

int Queue_Enqueue(SQueue *queue, Elem *elem)
{
    pthread_mutex_lock(&(queue->queue_lock));

    if(Queue_isFull(queue)){
        return -1;              //队列满
    }
    memcpy(&queue->elem[queue->rear], elem, sizeof(Elem));         //结构体copy。 todo...
    queue->rear = (queue->rear + 1) % QUEUE_MAXSIZE;

    pthread_mutex_unlock(&(queue->queue_lock));

    pthread_cond_signal (&(queue->queue_ready));
    return 0;
}

int Queue_Dequeue(SQueue *queue, Elem *elem)
{
    //pthread_mutex_lock(&(queue->queue_lock));
    if(Queue_isEmpty(queue)) {        
        //return -1;              /* 队列空 */
        printf ("thread 0x%ld is waiting\n", pthread_self ());  
        pthread_cond_wait (&(queue->queue_ready), &(queue->queue_lock));
    }
     memcpy(elem, &queue->elem[queue->front], sizeof(Elem));
     queue->front = (queue->front+1) % QUEUE_MAXSIZE;

     //pthread_mutex_unlock(&(queue->queue_lock));``
     return 0;
}


void *thread_routine()
{
    Elem *bufelem = (Elem*)malloc(sizeof(Elem));
    printf("create bufelem ing...\n");
   
    while(1)
    {
        memset(bufelem, 0, sizeof(Elem));
        
        pthread_mutex_lock(&(q->queue_lock));
        Queue_Dequeue(q, bufelem);
        pthread_mutex_unlock(&(q->queue_lock));

        printf("in thread_routine queue len:%d\n", Queue_Length(q));
        
        if (bufelem == NULL) {
           printf("出队失败，elem为空!!!\n");
              return NULL;
          }
   
         if (sockfd == 0)
         {
             printf("server socket is null...\n");
             return NULL;
         } 
    
    printf ("threadid is 0x%ld, working on task %d\n", pthread_self (),bufelem->msg.id); 
    //发送数据到客户端
    sendto(sockfd, info, SEND_MSGSIZE, 0, (struct sockaddr *)&bufelem->client, sin_size);
        
    }
    free(bufelem);
    bufelem = NULL;
}



int Queue_Destroy(SQueue *queue)
{
    return 0;
}

void Queue_Traverse(SQueue *queue)
{
    int i = queue ->front;
    printf("队中的元素是:\n");
    while(i % QUEUE_MAXSIZE != queue ->rear)
    {
        char data[256] = {'\0'};
        //printf("当前时间：%s----数据：%s\n", queue ->elem[i].msg.time, queue->elem[i].msg.data);
        sprintf(data, "recvmsg id:%d; time:%s; data:%s; data lengh:%d\nclient addr:%s\nclient port:%d", queue->elem[i].msg.id, queue->elem[i].msg.time, queue->elem[i].msg.data, queue->elem[i].msg.lengh, inet_ntoa(queue->elem[i].client.sin_addr), queue->elem[i].client.sin_port);
        //i++;
        printf("------data:%s\n", data);
        i=(i+1) % QUEUE_MAXSIZE;
    }
    printf("\n");
}